<template>
  <div 
    class="node" 
    :class="[nodeTypeClass, { 'selected': isSelected, 'dragging': isDragging }]"
    :style="nodeStyle"
    @mousedown="handleNodeMouseDown"
  >
    <div class="node-header">
      {{ getNodeTypeName }}
    </div>
    <div class="node-body">
      <!-- 输入端口 -->
      <div class="node-inputs">
        <div 
          v-for="(input, index) in node.inputs" 
          :key="index"
          class="node-port node-input"
          :class="input.type"
          @mouseup="handlePortMouseUp('input', index, $event)"
        >
        <div class="port-dot"></div>
          <span class="port-label">{{ input.name }}</span>
        </div>
      </div>
      
      <!-- 输出端口 -->
      <div class="node-outputs">
        <div 
          v-for="(output, index) in node.outputs" 
          :key="index"
          class="node-port node-output"
          :class="output.type"
          @mousedown="handlePortMouseDown('output', index, $event)"
        >
          <span class="port-label">{{ output.name }}</span>
          <div class="port-dot"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, inject, nextTick, watch, onMounted } from 'vue';

// Props
const props = defineProps({
  node: {
    type: Object,
    required: true
  },
  isSelected: {
    type: Boolean,
    default: false
  }
});

// Emits
const emit = defineEmits(['update:position', 'update:size', 'select', 'connection-drag-start', 'connection-created', 'connection-drag-end']);

// Injected values - 确保注入的是响应式引用
const scale = inject('scale');
const translateX = inject('translateX');
const translateY = inject('translateY');
const draggingSourceNode = inject('draggingSourceNode');
const draggingSourcePortIndex = inject('draggingSourcePortIndex');

// Reactive state
const isDragging = ref(false);
const dragOffsetX = ref(0);
const dragOffsetY = ref(0);
const hasMoved = ref(false);
const sourcePortIndex = ref(-1);
const MIN_SIZE = 50;
const inputPortPositions = ref([]);
const outputPortPositions = ref([]);

// Computed properties
const nodeTypeClass = computed(() => ({
  'node-flow': props.node.type === 'flow',
  'node-procedure': props.node.type === 'procedure',
  'node-product': props.node.type === 'product'
}));

const nodeStyle = computed(() => ({
  left: `${props.node.x}px`,
  top: `${props.node.y}px`,
  width: `${props.node.width}px`,
  height: `${props.node.height}px`,
  'border-left': props.node.type === 'flow' ? '4px solid #48bb78' : 
                props.node.type === 'procedure' ? '4px solid #4299e1' : 
                '4px solid #9f7aea'
}));

const getNodeTypeName = computed(() => 
  props.node.type === 'product' ? '产品节点' : 
  props.node.type === 'flow' ? '流程节点' : '过程节点'
);

// Methods
const updatePortPositions = () => {
  nextTick(() => {
    // 更新输入端点坐标
    inputPortPositions.value = props.node.inputs.map((input, index) => {
      // 获取当前节点的DOM元素
      const nodeElement = document.querySelector(`.node[style*="left: ${props.node.x}px"][style*="top: ${props.node.y}px"]`);
      
      if (nodeElement) {
        // 在当前节点内查找对应索引的输入端口
        const portElement = nodeElement.querySelectorAll('.node-input')[index];
        
        if (portElement) {
          const portRect = portElement.getBoundingClientRect();
          const editorRect = portElement.closest('.node-editor').getBoundingClientRect();
          
          const portX = (portRect.left + portRect.width / 2 - editorRect.left - translateX.value) / scale.value;
          const portY = (portRect.top + portRect.height / 2 - editorRect.top - translateY.value) / scale.value;
          
          return { x: portX, y: portY };
        }
      }
      return { x: props.node.x + input.x, y: props.node.y + input.y };
    });
    
    // 更新输出端点坐标
    outputPortPositions.value = props.node.outputs.map((output, index) => {
      // 获取当前节点的DOM元素
      const nodeElement = document.querySelector(`.node[style*="left: ${props.node.x}px"][style*="top: ${props.node.y}px"]`);
      
      if (nodeElement) {
        // 在当前节点内查找对应索引的输出端口
        const portElement = nodeElement.querySelectorAll('.node-output')[index];
        
        if (portElement) {
          const portRect = portElement.getBoundingClientRect();
          const editorRect = portElement.closest('.node-editor').getBoundingClientRect();
          
          const portX = (portRect.left + portRect.width / 2 - editorRect.left - translateX.value) / scale.value;
          const portY = (portRect.top + portRect.height / 2 - editorRect.top - translateY.value) / scale.value;
          
          return { x: portX, y: portY };
        }
      }
      return { x: props.node.x + output.x, y: props.node.y + output.y };
    });
  });
};

const handlePortMouseDown = (portType, index, event) => {
  if (portType === 'output') {
    sourcePortIndex.value = index;
    const portPosition = outputPortPositions.value[index];
    
    // 确保在设置draggingSourceNode之前先创建一个新的对象引用
    // 这样可以确保Vue的响应式系统能够检测到变化
    draggingSourceNode.value = {...props.node};
    draggingSourcePortIndex.value = index;
    
    // 打印日志以便调试
    console.log('设置拖拽源节点:', {
      nodeId: props.node.id,
      portIndex: index,
      position: portPosition
    });
    
    emit('connection-drag-start', {
      sourceNode: props.node,
      sourcePortIndex: index,
      startX: portPosition.x,
      startY: portPosition.y,
      clientX: event.clientX,
      clientY: event.clientY
    });
    
    event.stopPropagation();
  }
};

const handlePortMouseUp = (portType, index, event) => {
  if (portType === 'input') {
    // 使用注入的draggingSourceNode
    if (draggingSourceNode.value) {
      const portPosition = inputPortPositions.value[index];
      const targetPort = event.target.closest('.node-port');
      
      if (targetPort) {
        emit('connection-created', {
          source: draggingSourceNode.value.id,
          sourcePortIndex: draggingSourcePortIndex.value,
          target: props.node.id,
          targetPortIndex: index,
          targetPortPosition: portPosition
        });
        
        emit('connection-drag-end');
      }
    }
  }
};

const handleNodeMouseDown = (e) => {
  if (e.target.classList.contains('node-header') || 
      e.target.classList.contains('node-body')) {
    if (!e.target.closest('.node-port')) {
      isDragging.value = e.target.classList.contains('node-header');
      hasMoved.value = false;
      dragOffsetX.value = e.clientX - props.node.x;
      dragOffsetY.value = e.clientY - props.node.y;
      
      if (props.isSelected) {
        emit('select', null);
      }
      
      document.addEventListener('mousemove', handleDrag);
      document.addEventListener('mouseup', stopDrag);
    }
  }
};

const handleDrag = (e) => {
  if (!isDragging.value) return;
  hasMoved.value = true;
  updatePortPositions();
  
  emit('update:position', {
    id: props.node.id,
    position: {
      x: e.clientX - dragOffsetX.value,
      y: e.clientY - dragOffsetY.value
    },
    portPositions: {
      inputs: inputPortPositions.value,
      outputs: outputPortPositions.value
    }
  });
};

const stopDrag = () => {
  isDragging.value = false;
  document.removeEventListener('mousemove', handleDrag);
  document.removeEventListener('mouseup', stopDrag);
  
  if (!hasMoved.value) {
    emit('select', props.node);
  } else if (props.isSelected) {
    emit('select', props.node);
  }
  hasMoved.value = false;
};

// Watch for changes and update port positions
watch(
  () => [props.node.x, props.node.y, props.node.width, props.node.height],
  () => updatePortPositions(),
  { deep: true }
);

// Initialize port positions on mount
onMounted(() => {
  updatePortPositions();
});
</script>

<style>
@import '../assets/styles/node.css';
</style>